﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Graphics.Display;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using JiveMessenger.Utilities;
using System.Windows.Input;
using JiveMessenger.ViewModels;
using JmShared;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace JiveMessenger.CustomControls
{
    public sealed partial class NotificationsControl : UserControl, INotifyPropertyChanged
    {
        private SymbolIcon _symbolIconDelete;
        private SymbolIcon _symbolIconAccept;
        private bool _crossedAcceptThreshold;
        private bool _crossedDeleteThreshold;
        private bool _deleteFlickOccured;
        private bool _pinFlickOccured;
        private static double FLICK_VELOCITY = 1.5;

        private double _contactControlWidth;
        public double ContactControlWidth
        {
            get { return _contactControlWidth; }
            set
            {
                if (_contactControlWidth != value)
                {
                    _contactControlWidth = value;
                    RaisePropertyChanged("ContactControlWidth");
                }
            }
        }
        //    public static readonly DependencyProperty DeclineNotificationCommandProperty =
        //DependencyProperty.Register(
        //    "DeclineNotificationCommand",
        //    typeof(ICommand),
        //    typeof(NotificationsControl), new PropertyMetadata(null));

        //    public ICommand DeclineNotificationCommand
        //    {
        //        get { return (ICommand)GetValue(DeclineNotificationCommandProperty); }
        //        set { SetValue(DeclineNotificationCommandProperty, value); }
        //    }

        //    public static readonly DependencyProperty AcceptNotificationCommandProperty =
        //    DependencyProperty.Register(
        //    "AcceptNotificationCommand",
        //    typeof(ICommand),
        //    typeof(NotificationsControl), new PropertyMetadata(null));

        //    public ICommand AcceptNotificationCommand
        //    {
        //        get { return (ICommand)GetValue(AcceptNotificationCommandProperty); }
        //        set { SetValue(AcceptNotificationCommandProperty, value); }
        //    }


        public NotificationsControl()
        {
            this.InitializeComponent();
            this.ListViewNotifications.Background = new SolidColorBrush(Colors.Transparent);
        }
        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void OrientationChanged(DisplayInformation sender, object args)
        {
            //if (sender.CurrentOrientation == DisplayOrientations.Portrait || sender.CurrentOrientation == DisplayOrientations.PortraitFlipped)
            //    this.ItemTemplate = (DataTemplate)Resources["ContactListPortraitTemplate"];
            //else
            //    this.ContactList.ItemTemplate = (DataTemplate)Resources["ContactListLandscapeTemplate"];

        }
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            DisplayInformation.GetForCurrentView().OrientationChanged += OrientationChanged;
        }
        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            DisplayInformation.GetForCurrentView().OrientationChanged -= OrientationChanged;
        }

        private void ListViewNotifications_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ContactControlWidth = e.NewSize.Width;
        }
        private void NotificationItem_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {

            // initialize the drag
            FrameworkElement fe = sender as FrameworkElement;
            fe.SetHorizontalOffset(0);
            _pinFlickOccured = false;
            _deleteFlickOccured = false;
            _crossedAcceptThreshold = false;
            var descendants = fe.Descendants();
            // find the container for the pin and trash graphics
            _symbolIconDelete = descendants
                                       .OfType<SymbolIcon>()
                                       .Single(i => i.Name == "SymbolIconDelete");
            _symbolIconAccept = descendants
                                .OfType<SymbolIcon>()
                                .Single(i => i.Name == "SymbolIconAccept");


            //_pinTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/Pinned_Down_White.png"));
            //_removeTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/AppBar/ApplicationBar.Delete.White.png"));

        }


        private void NotificationItem_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;
            double offset = fe.GetHorizontalOffset().Value + e.Delta.Translation.X;
            fe.SetHorizontalOffset(offset);
            _pinFlickOccured = false;
            _deleteFlickOccured = false;

            if (e.Velocities.Linear.X < -FLICK_VELOCITY && !_deleteFlickOccured)
            {
                _deleteFlickOccured = true;
             //   Debug.WriteLine("Flicked item to decline");
            }
            else if (e.Velocities.Linear.X > FLICK_VELOCITY && !_pinFlickOccured)
            {
                _pinFlickOccured = true;

             //   Debug.WriteLine("Flicked item to accept");
            }

            // _pinAndTrashContainer.Opacity = PinAndTrashOpacity(offset);


            if ((e.Cumulative.Translation.X > fe.ActualWidth / 2.5 || _pinFlickOccured))
            {
                if (!_crossedAcceptThreshold)
                {
                    //  _pinTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/Pinned_Down_Green.png"));
                    _symbolIconAccept.Foreground = new SolidColorBrush(Colors.Green);
                    _crossedAcceptThreshold = true;
                }
            }
            else if ((e.Cumulative.Translation.X < -fe.ActualWidth / 2.5 || _deleteFlickOccured))
            {
                if (!_crossedDeleteThreshold)
                {
                    // _removeTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/AppBar/ApplicationBar.Delete.Red.png"));
                    _symbolIconDelete.Foreground = new SolidColorBrush(Colors.Red);
                    _crossedDeleteThreshold = true;
                }
            }
            else if (_crossedAcceptThreshold || _crossedDeleteThreshold)
            {
                //  _pinTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/Pinned_Down_White.png"));
                // _removeTabImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/AppBar/ApplicationBar.Delete.White.png"));
                _symbolIconAccept.Foreground = Application.Current.Resources["PhoneForegroundBrush"] as SolidColorBrush;
                _symbolIconDelete.Foreground = Application.Current.Resources["PhoneForegroundBrush"] as SolidColorBrush;
                _crossedAcceptThreshold = false;
                _crossedDeleteThreshold = false;
            }

            e.Handled = true;
        }

        private void Grid_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;
            if (_crossedDeleteThreshold || _crossedAcceptThreshold)
            {
                if (_crossedDeleteThreshold || _deleteFlickOccured)
                {
                    NotificationItemDeletedAction(fe);
                }
                else
                {
                    NotificationItemCompletedAction(fe);
                }
            }
            else
            {
                NotificationItemBounceBack(fe);
            }

        }
        private void NotificationItemDeletedAction(FrameworkElement deletedElement)
        {
            // _deleteSound.Play();

            var trans = deletedElement.GetHorizontalOffset().Transform;
            trans.Animate(trans.X, -(deletedElement.ActualWidth + 70),
                          "TranslateTransform.X", 300, 0, FillBehavior.HoldEnd, new SineEase()
                          {
                              EasingMode = EasingMode.EaseOut
                          },
            () =>
            {
                // find the model object that was deleted
                deletedElement.Opacity = 0;
                //if (DeclineNotificationCommand != null)
                //    DeclineNotificationCommand.Execute(deletedElement.DataContext);
                NotificationBase notification = (NotificationBase)deletedElement.DataContext;
                notification.IsSelected = true;
                ViewModelNotifications vm = (ViewModelNotifications)this.DataContext;
                vm.DeclineInviteCommand.Execute(null);
                _deleteFlickOccured = false;
                deletedElement.RenderTransform = new CompositeTransform();
            });
        }
        private void NotificationItemCompletedAction(FrameworkElement fe)
        {
            // set the ToDoItem to complete
            //if (AcceptNotificationCommand != null)
            //    AcceptNotificationCommand.Execute(fe.DataContext);
            // bounce back into place
            NotificationBase notification = (NotificationBase)fe.DataContext;
            notification.IsSelected = true;
            ViewModelNotifications vm = (ViewModelNotifications)this.DataContext;
            vm.AcceptInviteCommand.Execute(null);
            NotificationItemBounceBack(fe);
        }
        private void NotificationItemBounceBack(FrameworkElement fe)
        {
            var trans = fe.GetHorizontalOffset().Transform;

            string propertyPath = "TranslateTransform.X";
            trans.Animate(trans.X, 0, propertyPath, 300, 0, FillBehavior.HoldEnd, new BounceEase()
            {
                Bounciness = 5,
                Bounces = 2
            }, () =>
            {
                fe.Tag = null;
            });
        }
    }
}
